package obs;

import com.google.gson.Gson;
import com.obs.services.ObsClient;
import com.obs.services.ObsConfiguration;
import com.obs.services.exception.ObsException;
import com.obs.services.internal.utils.ServiceUtils;
import com.obs.services.model.*;

import java.text.ParseException;
import java.util.List;

/**
 * Title: BucketOperationsSample
 * Description: 桶相关接口  用法 示例
 *
 * @author hfl
 * @version V1.0
 * @date 2020-05-25
 */
public class BucketOperationsSample {
    private static final String endPoint = "http://obs.cn-north-4.myhuaweicloud.com";
    private static final String ak = "NNNNWPW2FZHMYPRB3M79OBXXX";
    private static final String sk = "7ZRRRRX0kNN0SgsxtIsB6EBZGygWvpC04mezuT0pbBBBPu";
    private static ObsClient obsClient;
    private static String bucketName = "wuzheng-demo";
    private static final String g_bucketLoc = "cn-north-4";

    //初始化obs配置
    static {
        ObsConfiguration config = new ObsConfiguration();
        config.setSocketTimeout(30000);
        config.setConnectionTimeout(10000);
        config.setEndPoint(endPoint);
        obsClient = new ObsClient(ak, sk, config);

    }

    private static void liftConfig(String bucketName) {
        LifecycleConfiguration config = new LifecycleConfiguration();
        LifecycleConfiguration.Rule rule = config.new Rule();
        rule.setEnabled(true);
        rule.setId("rule1");
        rule.setPrefix("");
        LifecycleConfiguration.Expiration expiration = config.new Expiration();
        // 指定满足前缀的对象创建60天后过期
        expiration.setDays(1);
        // 直接指定满足前缀的对象过期时间
        // expiration.setDate(new SimpleDateFormat("yyyy-MM-dd").parse("2018-12-31"));
        rule.setExpiration(expiration);

        LifecycleConfiguration.NoncurrentVersionExpiration noncurrentVersionExpiration = config.new NoncurrentVersionExpiration();
        // 指定满足前缀的对象成为历史版本60天后过期
        noncurrentVersionExpiration.setDays(1);
        rule.setNoncurrentVersionExpiration(noncurrentVersionExpiration);
        config.addRule(rule);

        obsClient.setBucketLifecycle(bucketName, config);
    }


    //创建一个桶的方法
    //bug解决，必须传一个g_bucketLoc 参数到构造方法，官方文档好坑啊
    //https://blog.csdn.net/qq_39295735/article/details/83304525
    public static void createBucket() {
        ObsBucket obsBucket = new ObsBucket(bucketName, g_bucketLoc);
        obsBucket.setBucketName(bucketName);
        obsClient.createBucket(obsBucket);
        System.out.println("Create bucket:" + bucketName + " successfully!\n");
    }

    //获取桶区域位置
    public static void getBucketLocation() {
        String location = obsClient.getBucketLocation(bucketName);
        System.out.println("Getting bucket location " + location + "\n");
    }

    // 获取存储桶storageInfo操作
    public static void getBucketStorageInfo() {
        BucketStorageInfo storageInfo = obsClient.getBucketStorageInfo(bucketName);
        System.out.println("Getting bucket storageInfo " + storageInfo + "\n");
    }


    //设置桶配额
    public static void doBucketQuotaOperation() {
        BucketQuota quota = new BucketQuota();
        //Set bucket quota to 1GB
        //quota.setBucketQuota(1024 * 1024 * 1024L);
        // 设置桶配额为100MB
        quota.setBucketQuota(1024 * 1024 * 100L);
        obsClient.setBucketQuota(bucketName, quota);
        System.out.println("Getting bucket quota " + obsClient.getBucketQuota(bucketName) + "\n");
    }


    //设置/获取 存储桶 版本控制 操作
    public static void doBucketVersioningOperation() {
        System.out.println("Getting bucket versioning config " + obsClient.getBucketVersioning(bucketName) + "\n");
        //Enable bucket versioning
        obsClient.setBucketVersioning(bucketName, new BucketVersioningConfiguration(VersioningStatusEnum.ENABLED));
        System.out.println("Current bucket versioning config " + obsClient.getBucketVersioning(bucketName) + "\n");
        //Suspend bucket versioning
        BucketVersioningConfiguration suspended = new BucketVersioningConfiguration(VersioningStatusEnum.SUSPENDED);
        obsClient.setBucketVersioning(bucketName, suspended);
        System.out.println("Current bucket versioning config " + obsClient.getBucketVersioning(bucketName) + "\n");
    }

    //设置/获取存储桶ACL
    public static void doBucketAclOperation() {
        System.out.println("Setting bucket ACL to public-read \n");
        //设置桶访问权限为公共读，默认是私有读写
        obsClient.setBucketAcl(bucketName, AccessControlList.REST_CANNED_PUBLIC_READ_WRITE);
        System.out.println("Getting bucket ACL " + obsClient.getBucketAcl(bucketName) + "\n");
        //System.out.println("Setting bucket ACL to private \n");
        // obsClient.setBucketAcl(bucketName, AccessControlList.REST_CANNED_PRIVATE);
        // System.out.println("Getting bucket ACL " + obsClient.getBucketAcl(bucketName) + "\n");
    }


    //设置/获取/删除存储桶cors操作
    public static void doBucketCorsOperation() {
        BucketCors bucketCors = new BucketCors();
        BucketCorsRule rule = new BucketCorsRule();
        rule.getAllowedHeader().add("Authorization");
        rule.getAllowedOrigin().add("http://www.a.com");
        rule.getAllowedOrigin().add("http://www.b.com");
        rule.getExposeHeader().add("x-obs-test1");
        rule.getExposeHeader().add("x-obs-test2");
        rule.setMaxAgeSecond(100);
        rule.getAllowedMethod().add("HEAD");
        rule.getAllowedMethod().add("GET");
        rule.getAllowedMethod().add("PUT");
        bucketCors.getRules().add(rule);

        System.out.println("Setting bucket CORS\n");
        obsClient.setBucketCors(bucketName, bucketCors);
        System.out.println("Getting bucket CORS:" + obsClient.getBucketCors(bucketName) + "\n");
    }


    //列举桶
    //目前的所有桶
    //develop-bucket
    //temp-bucket
    //wuzheng-demo
    //css-backup-1589872173973
    //css-backup-1590042161374
    public static void listBuckets() throws ObsException {
        ListBucketsRequest request = new ListBucketsRequest();
        request.setQueryLocation(true);
        List<ObsBucket> buckets = obsClient.listBuckets(request);
        for (ObsBucket bucket : buckets) {
            System.out.println("BucketName:" + bucket.getBucketName());
            System.out.println("CreationDate:" + bucket.getCreationDate());
            System.out.println("Location:" + bucket.getLocation());
        }
    }

    //桶选项
    public static void optionsBucket() throws ObsException {
        System.out.println("Options bucket\n");
        OptionsInfoRequest optionInfo = new OptionsInfoRequest();
        optionInfo.setOrigin("http://www.a.com");
        optionInfo.getRequestHeaders().add("Authorization");
        optionInfo.getRequestMethod().add("PUT");
        System.out.println(obsClient.optionsBucket(bucketName, optionInfo));


    }

    //获取存储桶元数据
    public static void getBucketMetadata() throws ObsException {
        System.out.println("Getting bucket metadata\n");
        BucketMetadataInfoRequest request = new BucketMetadataInfoRequest(bucketName);
        request.setOrigin("http://www.a.com");
        request.getRequestHeaders().add("Authorization");
        // 获取桶元数据
        BucketMetadataInfoResult result = obsClient.getBucketMetadata(request);
        System.out.println("StorageClass:" + result.getBucketStorageClass());
        System.out.println("\tAllowedOrigins " + result.getAllowOrigin());
        System.out.println("\tAllowedMethods " + result.getAllowMethods());
        System.out.println("\tAllowedHeaders " + result.getAllowHeaders());
        System.out.println("\tExposeHeaders " + result.getExposeHeaders());
        System.out.println("\tMaxAgeSeconds " + result.getMaxAge() + "\n");

        System.out.println("Deleting bucket CORS\n");
        obsClient.deleteBucketCors(bucketName);
    }

    //设置/获取/删除存储桶 生命周期 操作
    public static void doBucketLifecycleOperation() throws ObsException {
        final String ruleId0 = "delete obsoleted files";
        final String matchPrefix0 = "obsoleted/";
        final String ruleId1 = "delete temporary files";
        final String matchPrefix1 = "temporary/";
        final String ruleId2 = "delete temp files";
        final String matchPrefix2 = "temp/";

        LifecycleConfiguration lifecycleConfig = new LifecycleConfiguration();
        LifecycleConfiguration.Rule rule0 = lifecycleConfig.new Rule();
        rule0.setEnabled(true);
        rule0.setId(ruleId0);
        rule0.setPrefix(matchPrefix0);
        LifecycleConfiguration.Expiration expiration0 = lifecycleConfig.new Expiration();
        expiration0.setDays(10);

        rule0.setExpiration(expiration0);
        lifecycleConfig.addRule(rule0);

        LifecycleConfiguration.Rule rule1 = lifecycleConfig.new Rule();
        rule1.setEnabled(true);
        rule1.setId(ruleId1);
        rule1.setPrefix(matchPrefix1);
        LifecycleConfiguration.Expiration expiration1 = lifecycleConfig.new Expiration();
        try {
            expiration1.setDate(ServiceUtils.parseIso8601Date("2018-12-31T00:00:00"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        rule1.setExpiration(expiration1);
        lifecycleConfig.addRule(rule1);

        LifecycleConfiguration.Rule rule2 = lifecycleConfig.new Rule();
        rule2.setEnabled(true);
        rule2.setId(ruleId2);
        rule2.setPrefix(matchPrefix2);
        LifecycleConfiguration.NoncurrentVersionExpiration noncurrentVersionExpiration = lifecycleConfig.new NoncurrentVersionExpiration();
        noncurrentVersionExpiration.setDays(10);
        rule2.setNoncurrentVersionExpiration(noncurrentVersionExpiration);
        lifecycleConfig.addRule(rule2);

        System.out.println("Setting bucket lifecycle\n");
        obsClient.setBucketLifecycleConfiguration(bucketName, lifecycleConfig);

        System.out.println("Getting bucket lifecycle:");
        LifecycleConfiguration result = obsClient.getBucketLifecycleConfiguration(bucketName);
        LifecycleConfiguration.Rule r0 = result.getRules().get(0);
        LifecycleConfiguration.Rule r1 = result.getRules().get(1);
        LifecycleConfiguration.Rule r2 = result.getRules().get(2);
        System.out.println("\tRule0: Id=" + r0.getId() + ", Prefix=" + r0.getPrefix() + ", Status=" + r0.getEnabled() + ", ExpirationDays="
                + r0.getExpiration().getDays());
        System.out.println("\tRule1: Id=" + r1.getId() + ", Prefix=" + r1.getPrefix() + ", Status=" + r1.getEnabled() + ", ExpirationTime="
                + r1.getExpiration().getDate());

        System.out.println("\tRule1: Id=" + r2.getId() + ", Prefix=" + r2.getPrefix() + ", Status=" + r2.getEnabled()
                + ", NocurrentExpirationDays=" + r2.getNoncurrentVersionExpiration().getDays());
        System.out.println();

        System.out.println("Deleting bucket lifecycle\n");
        obsClient.deleteBucketLifecycleConfiguration(bucketName);
    }

    //设置/获取/删除存储桶日志记录操作
    public static void doBucketLoggingOperation() throws ObsException {
        final String targetBucket = bucketName;
        final String targetPrefix = "log-";
        BucketLoggingConfiguration configuration = new BucketLoggingConfiguration();
        configuration.setTargetBucketName(targetBucket);
        configuration.setLogfilePrefix(targetPrefix);
        configuration.setAgency("test");

        System.out.println("Setting bucket logging\n");
        obsClient.setBucketLoggingConfiguration(bucketName, configuration, true);

        System.out.println("Getting bucket logging:");
        BucketLoggingConfiguration result = obsClient.getBucketLoggingConfiguration(bucketName);
        System.out.println("\tTarget bucket=" + result.getTargetBucketName() + ", target prefix=" + result.getLogfilePrefix() + "\n");
        System.out.println();

        System.out.println("Deleting bucket logging\n");
        obsClient.setBucketLoggingConfiguration(targetBucket, new BucketLoggingConfiguration());
    }

    //设置/获取/删除存储桶网站操作
    public static void doBucketWebsiteOperation() throws ObsException {

        WebsiteConfiguration websiteConfig = new WebsiteConfiguration();
        websiteConfig.setSuffix("index.html");
        websiteConfig.setKey("error.html");

        System.out.println("Setting bucket website\n");
        obsClient.setBucketWebsiteConfiguration(bucketName, websiteConfig);

        System.out.println("Getting bucket website:");
        WebsiteConfiguration result = obsClient.getBucketWebsiteConfiguration(bucketName);
        System.out.println("\tIndex document=" + result.getKey() + ", error document=" + result.getSuffix() + "\n");

        System.out.println("Deleting bucket website\n");
        obsClient.deleteBucketWebsiteConfiguration(bucketName);
    }

    //设置/获取/删除存储桶标签操作
    public static void doBucketTaggingOperation() throws ObsException {

        System.out.println("Setting bucket tagging\n");

        BucketTagInfo tagInfo = new BucketTagInfo();
        BucketTagInfo.TagSet tagSet = new BucketTagInfo.TagSet();
        tagSet.addTag("key1", "value1");
        tagSet.addTag("key2", "value2");
        tagInfo.setTagSet(tagSet);

        obsClient.setBucketTagging(bucketName, tagInfo);

        System.out.println("Getting bucket tagging\n");

        System.out.println(obsClient.getBucketTagging(bucketName));

        System.out.println("Deleting bucket tagging\n");
        obsClient.deleteBucketTagging(bucketName);
    }

    //设置/获取/删除 存储桶加密
    public static void doBucketEncryptionOperation() throws ObsException {
        System.out.println("Setting bucket encryption\n");

        BucketEncryption encryption = new BucketEncryption(SSEAlgorithmEnum.KMS);
//      encryption.setKmsKeyId("your kmsKeyId");
        obsClient.setBucketEncryption(bucketName, encryption);

        System.out.println("Gettting bucket encryption\n");
        System.out.println(obsClient.getBucketEncryption(bucketName));

        System.out.println("Deleting bucket encryption\n");
        obsClient.deleteBucketEncryption(bucketName);
    }

    //删除存储桶
    public static void deleteBucket() throws ObsException {
        System.out.println("Deleting bucket " + bucketName + "\n");
        obsClient.deleteBucket(bucketName);
    }

    //判断桶是否存在
    public static void headBucket() throws ObsException {
        boolean b = obsClient.headBucket(bucketName);
        System.out.println("是否存在 bucket " + bucketName + "\n" + b);

    }

    //设置桶存储类型 和获取通存储类型
    public static void bucketStorage() throws ObsException {
        // 设置桶的存储类型为标准存储.
        BucketStoragePolicyConfiguration storgePolicy = new BucketStoragePolicyConfiguration();
        storgePolicy.setBucketStorageClass(StorageClassEnum.STANDARD);
        obsClient.setBucketStoragePolicy(bucketName, storgePolicy);

        //获取桶存储类型
        BucketStoragePolicyConfiguration storagePolicy = obsClient.getBucketStoragePolicy(bucketName);
        System.out.println("\t" + storagePolicy.getBucketStorageClass());
    }

    //暂时不考虑用: 查看桶多版本状态
    private static void viewBuckVersions(String bucketname) {
        BucketVersioningConfiguration status = obsClient.getBucketVersioning(bucketname);
        System.out.println("\t" + status.getVersioningStatus());
    }

    //删除生命周期
    private static void deleteBucketLifecycle(String bucketName) {
        HeaderResponse response = obsClient.deleteBucketLifecycle(bucketName);
        System.out.println(new Gson().toJson(response));
    }

    //查看生命周期规则（没设置的话，调用会报错）
    public static void viewLifeCycleConfigration(String bucketName) {
        LifecycleConfiguration config = obsClient.getBucketLifecycle(bucketName);
        for (LifecycleConfiguration.Rule rule : config.getRules()) {
            System.out.println(rule.getId());
            System.out.println(rule.getPrefix());
            System.out.println(rule.getExpiration().getDate());
            for (LifecycleConfiguration.Transition transition : rule.getTransitions()) {
                System.out.println(transition.getDays());
                System.out.println(transition.getStorageClass());
            }
            System.out.println(rule.getExpiration() != null ? rule.getExpiration().getDays() : "");
            for (LifecycleConfiguration.NoncurrentVersionTransition noncurrentVersionTransition : rule.getNoncurrentVersionTransitions()) {
                System.out.println(noncurrentVersionTransition.getDays());
                System.out.println(noncurrentVersionTransition.getStorageClass());
            }
            System.out.println(rule.getNoncurrentVersionExpiration() != null ? rule.getNoncurrentVersionExpiration().getDays() : "");
        }
    }


    public static void main(String[] args) {
        //创建一个桶
        //createBucket();
        //getBucketLocation();
        //  getBucketStorageInfo();
        //设置桶配额  获取桶配额
        // doBucketQuotaOperation();
        //设置读的公有 和私有权限
        //doBucketAclOperation();
        //列举桶
        listBuckets();
        //删除桶
        //deleteBucket();
        //判断桶是否存在
        //headBucket();
        //获取桶元数据
        //getBucketMetadata();
        //获取桶区域位置
        //getBucketLocation();
        //设置桶存储类型 和获取通存储类型
        //bucketStorage();
        //查看桶多版本状态
        //viewBuckVersions(bucketName);
        //设置对象过期时间(生命周期规则)
        //liftConfig("wuzheng-demo");
        //查看生命周期规则
        //viewLifeCycleConfigration("wuzheng-demo");
        //删除生命周期规则
        //deleteBucketLifecycle("wuzheng-demo");
        //查看桶日志配置
        //getBucketLogging();


    }

    //查看桶日志配置
    public static void getBucketLogging() {
        BucketLoggingConfiguration config = obsClient.getBucketLogging(bucketName);
        System.out.println("\t" + config.getTargetBucketName());
        System.out.println("\t" + config.getLogfilePrefix());
    }


}
